package com.traffic.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.traffic.constant.Status;
import com.traffic.entity.*;
import com.traffic.exception.BaseException;
import com.traffic.model.ApiResponse;
import com.traffic.model.PushUser;
import com.traffic.service.UserInfoService;
import com.traffic.service.UserService;
import com.traffic.util.DataUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/9/3
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping(value = "/users")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private UserInfoService userInfoService ;

    @Autowired
    private DataUtil dataUtil;

    @ApiOperation(value = "【登录注册】", notes = "验证码登录")
    //@ApiImplicitParam(paramType = "path", dataType = "String", name = "accessToken", value = "一键登录三方SDK返回的验证字符串", required = true)
    @GetMapping("/loginOrRegister/{phone}")
    public ApiResponse loginOrRegister(@PathVariable String phone) {
        String token = userService.loginOrRegister(phone);
        if (StrUtil.isNotEmpty(token)) {
            return ApiResponse.ofStatus(Status.OK, token);
        }else {
            return ApiResponse.ofStatus(Status.LOGIN_ERROR);
        }
    }

    @ApiOperation(value = "【登录注册】", notes = "验证是否登录")
    @ApiImplicitParam(paramType = "path", dataType = "String", name = "account", value = "用户的登录手机号", required = true)
    @GetMapping("/isLogin/{account}")
    public ApiResponse isLogin(@PathVariable String account) {
        if (userService.isLogin(account)) {
            return ApiResponse.ofStatus(Status.OK);
        }
        return ApiResponse.ofStatus(Status.NOT_ERROR);
    }

    @ApiOperation(value = "【个人中心-基础设置】", notes = "注销登录，需要在请求头中添加Token")
    @ApiImplicitParam(paramType = "path", dataType = "String", name = "account", value = "用户的登录手机号", required = true)
    @GetMapping("/logout/{account}")
    public ApiResponse logout(@PathVariable String account) {
        if (userService.logout(account)) {
            return ApiResponse.ofStatus(Status.OK);
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }

    @ApiOperation(value = "【个人中心-个人信息】", notes = "获取用户详细信息，需要在请求头中添加Token")
    @ApiImplicitParam(paramType = "path", dataType = "String", name = "account", value = "用户的登录手机号", required = true)
    @GetMapping("/{account}")
    public ApiResponse getUserInfo(@PathVariable String account) {
        UserInfo userInfo = userInfoService.queryInfo(account);
        if (!ObjectUtil.isNull(userInfo)) {
            return ApiResponse.ofStatus(Status.OK, userInfo);
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }

    @ApiOperation(value = "【个人中心-个人信息】", notes = "更新用户详细信息，需要在请求头中添加Token，传入用户信息，Map对象")
    @ApiImplicitParam(paramType = "path", dataType = "String", name = "account", value = "用户的登录手机号", required = true)
    @PutMapping("/{account}")
    public ApiResponse updateUserInfo(@PathVariable String account, @RequestBody Map<String, Object> userInfo) {
        UserInfo old = userInfoService.queryInfo(account);
        if (ObjectUtil.isNotNull(old) && ObjectUtil.isNotNull(userInfo)) {
            // 对Map中的参数进行处理
            String param[] = new String[] {"nickName", "sex", "birthday", "city", "profile"};
            List<String> paramList = CollUtil.newArrayList(param);
            if (!paramList.containsAll(CollUtil.newArrayList(userInfo.keySet().toArray()))) {
                throw new BaseException(Status.PARAM_ERROR);
            }
            BeanUtil.copyProperties(userInfo, old, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            // log.error(String.valueOf(JSONUtil.parse(old)));
            UserInfo result = userInfoService.updateInfo(old);
            if (ObjectUtil.isNotNull(result)) {
                return ApiResponse.ofStatus(Status.OK, result);
            }
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }

    @ApiOperation(value = "【个人中心-上传修改头像】", notes = "先调用上传图片的接口，传入返回的id，需要token")
    @PostMapping("/headImg")
    public ApiResponse headImg(@RequestParam("account") String account, @RequestParam("id") Long id) {
        if (ObjectUtil.isNotEmpty(userInfoService.addOrUpdateHeadImg(account, id))) {
            return ApiResponse.ofStatus(Status.OK);
        }
        return ApiResponse.ofStatus(Status.COMMON_ERROR);
    }


    @ApiOperation(value = "【管理员通过user id查询userinfo】", notes = "query token")
    @GetMapping("/query/info/id/{id}")
    public ApiResponse queryUserInfoById(@PathVariable Long id) {
        return ApiResponse.ofStatus(Status.OK, userInfoService.getUserInfoByUserId(id));
    }

    @ApiOperation(value = "【管理员通过phone 查询userinfo】", notes = "query token")
    @GetMapping("/query/info/phone/{phone}")
    public ApiResponse queryUserInfoByPhone(@PathVariable String phone) {
        return ApiResponse.ofStatus(Status.OK, userInfoService.getUserInfoByPhone(phone));
    }

    @ApiOperation(value = "【管理员通过id 查询user】")
    @GetMapping("/query/user/id/{id}")
    public ApiResponse queryUserById(@PathVariable Long id) {
        PageResult result = userService.queryUserById(id);
        RtUserData rtUserData = dataUtil.dataChange(result.getUser());
        QueryResult queryResult = QueryResult.builder().data(rtUserData).total(result.getTotal()).build();
        return ApiResponse.ofStatus(Status.OK, queryResult);
    }

    @ApiOperation(value = "【管理员通过phone 查询user】")
    @GetMapping("/query/user/phone/{phone}")
    public ApiResponse queryUserByPhone(@PathVariable String phone) {
        PageResult result = userService.queryUserByPhone(phone);
        RtUserData rtUserData = dataUtil.dataChange(result.getUser());
        QueryResult queryResult = QueryResult.builder().data(rtUserData).total(result.getTotal()).build();
        return ApiResponse.ofStatus(Status.OK, queryResult);
    }

    @ApiOperation(value = "【管理员查询user 分页查询全部】")
    @GetMapping("query/user/page")
    public ApiResponse queryUserListPage(@RequestParam(defaultValue = "1") Integer currentPage, @RequestParam(defaultValue = "10") Integer pageSize) {
        PageResult result = userService.queryUserList(currentPage, pageSize);
        List<RtUserData> list = dataUtil.dataChange(result.getList());
        QueryResult queryResult = QueryResult.builder().data(list).total(result.getTotal()).build();
        return ApiResponse.ofStatus(Status.OK, queryResult);
    }

    @ApiOperation(value = "【管理员查询user 分页条件查询】")
    @GetMapping("query/user/wrapper")
    public ApiResponse queryUserListPageWithWrapper(@RequestParam(defaultValue = "1") Integer currentPage,
                                                    @RequestParam(defaultValue = "10") Integer pageSize,
                                                    @RequestParam Map<String, Object> param) {
        PageResult result = userService.queryUserList(param, currentPage, pageSize);
        List<RtUserData> list = dataUtil.dataChange(result.getList());
        QueryResult queryResult = QueryResult.builder().data(list).total(result.getTotal()).build();
        return ApiResponse.ofStatus(Status.OK, queryResult);
    }

    @ApiOperation(value = "【冻结账户】")
    @GetMapping("/frozen/{id}")
    public ApiResponse frozen(@PathVariable Long id) {
        return ApiResponse.ofStatus(Status.OK, userService.frozen(id));
    }

    @ApiOperation(value = "【解冻账户】")
    @GetMapping("/thaw/{id}")
    public ApiResponse thaw(@PathVariable Long id) {
        return ApiResponse.ofStatus(Status.OK, userService.thaw(id));
    }

    @ApiOperation(value = "【删除账户】")
    @DeleteMapping("/{id}")
    public ApiResponse deleteAccount(@PathVariable Long id) {
        return ApiResponse.ofStatus(Status.OK, userService.deleteAccount(id));
    }

    @ApiOperation(value = "【修改手机号】", notes = "先做短信验证，通过后调用本接口")
    @GetMapping("/phone/edit/{oldPhone}/{newPhone}")
    public ApiResponse editPhone(@PathVariable String oldPhone, @PathVariable String newPhone) {
        if (userService.editPhone(oldPhone, newPhone)) {
            return ApiResponse.ofStatus(Status.OK);
        }
        return ApiResponse.ofStatus(Status.COMMON_ERROR);
    }

    @ApiOperation(value = "【管理员通过手机号 查询user_id】")
    @GetMapping("/query/userid/{phone}")
    public ApiResponse queryUserIdByPhone(@PathVariable String phone) {

        Object userid = userService.getUserId(phone);

        String id = StringUtils.strip(userid.toString(),"[]");

        return ApiResponse.ofStatus(Status.OK, id);
    }


    @ApiOperation(value = "【更新推送设备id】")
    @GetMapping("/push/{userid}/{registrationid}")
    public ApiResponse pushregistration(@PathVariable Long userid,@PathVariable String registrationid) {

        User u = userService.getById(userid);

        u.setRegistrationid(registrationid);

        userService.updateById(u);

        return ApiResponse.ofStatus(Status.OK);
    }

    @ApiOperation(value = "【管理员通过phone或者昵称 查询user】")
    @GetMapping("/query/user/phonenickname/{phone}")
    public ApiResponse queryUserByPhoneNickname(@PathVariable String phone) {

        List<PushUser> users = userService.getuserRID(phone);

        return ApiResponse.ofStatus(Status.OK,users);
    }

    @ApiOperation(value = "【用户自己删除账户】")
    @GetMapping("/owner/delete/{id}")
    public ApiResponse userDeleteOwnAccount(@PathVariable Long id) {
        if (userService.userDeleteOwn(id)) {
            return ApiResponse.ofStatus(Status.OK);
        }else {
            return ApiResponse.ofStatus(Status.COMMON_ERROR);
        }
    }

}
